"""
加密工具类，用于公共参数的加密和解密
"""
import os
import base64
from cryptography.fernet import Fernet
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC


class CryptoManager:
    """加密管理器"""
    
    def __init__(self):
        # 使用环境变量中的密钥，如果没有则使用默认密钥
        self.secret_key = os.getenv('CRYPTO_SECRET_KEY', 'default-secret-key-change-in-production')
        self.salt = b'stable_salt_for_global_params'  # 固定盐值，确保加密解密一致
        self._fernet = None
    
    def _get_fernet(self):
        """获取Fernet实例"""
        if self._fernet is None:
            # 使用PBKDF2从密钥生成Fernet密钥
            kdf = PBKDF2HMAC(
                algorithm=hashes.SHA256(),
                length=32,
                salt=self.salt,
                iterations=100000,
            )
            key = base64.urlsafe_b64encode(kdf.derive(self.secret_key.encode()))
            self._fernet = Fernet(key)
        return self._fernet
    
    def encrypt(self, value: str) -> str:
        """加密字符串值"""
        if not value:
            return value
        
        try:
            fernet = self._get_fernet()
            encrypted_bytes = fernet.encrypt(value.encode('utf-8'))
            return base64.urlsafe_b64encode(encrypted_bytes).decode('utf-8')
        except Exception as e:
            raise Exception(f"加密失败: {str(e)}")
    
    def decrypt(self, encrypted_value: str) -> str:
        """解密字符串值"""
        if not encrypted_value:
            return encrypted_value
        
        try:
            fernet = self._get_fernet()
            # 先进行base64解码
            encrypted_bytes = base64.urlsafe_b64decode(encrypted_value.encode('utf-8'))
            # 然后解密
            decrypted_bytes = fernet.decrypt(encrypted_bytes)
            return decrypted_bytes.decode('utf-8')
        except Exception as e:
            raise Exception(f"解密失败: {str(e)}")


# 全局实例
_crypto_manager = CryptoManager()


def encrypt_value(value: str) -> str:
    """加密值的全局函数"""
    return _crypto_manager.encrypt(value)


def decrypt_value(encrypted_value: str) -> str:
    """解密值的全局函数"""
    return _crypto_manager.decrypt(encrypted_value)